﻿using Kimd.Common;
using Kimd.Communication;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkStation.Common;

namespace WorkStation.Logic
{
    /// <summary>
    /// Block供料
    /// </summary>
    public class FeedBlockLogic : FlowBase
    {
        private Axis _lift;
        private Axis _transfer;
        private Sensor _hasBlockMgz;
        private Sensor _plasmaIsRunning;
        private Sensor _plasmaAlarm;
        private Sensor _gt2OK;
        private Sensor _hasPlate;
        public FeedBlockLogic(string flowName, FlowManager flowmanager) 
            : base(flowName, flowmanager)
        {
            _lift = MachineResource.Instance.MachineAxis["Block升降"];
            _transfer = MachineResource.Instance.MachineAxis["Block平移"];
            _hasBlockMgz = MachineResource.Instance.MachineSensor["料盒有料光电"];
            _plasmaIsRunning = MachineResource.Instance.MachineSensor["等离子机运行"];
            _plasmaAlarm = MachineResource.Instance.MachineSensor["等离子机报警"];
            _gt2OK = MachineResource.Instance.MachineSensor["GT2测量OK"];
            _hasPlate = MachineResource.Instance.MachineSensor["料盘有料光电"];

            RegisterDirectSignal("Block可取料");
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            if (_lift.ServoWarn)
                _lift.ClearAlarm();
            Thread.Sleep(200);
            if (!_lift.ServoOn)
                _lift.SetServoOn();
            if (_transfer.ServoWarn)
                _transfer.ClearAlarm();
            Thread.Sleep(200);
            if (!_transfer.ServoOn)
                _transfer.SetServoOn();

            if (!CheckFlowCondition()) return;
            checkPlasmaStatus();
            if (!CheckFlowCondition()) return;
            //先回横移轴
            SingleAxisGoHome(_transfer);
            if (!CheckFlowCondition()) return;
            checkProductStatus();
            if (!CheckFlowCondition()) return;
            SingleAxisGoHome(_lift); 
            if (!CheckFlowCondition()) return;

            SingleAxisMove2Point(_lift, 0);
            if (!CheckFlowCondition()) return;
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }

        public override void InSingleRunMode()
        {
            base.InSingleRunMode();
        }

        public override void Method()
        {
            if (!CheckFlowCondition()) return;

            if (!GlobalVariable.IsDryRun)
            {
                WaitSensor(_hasBlockMgz, 0, "缺少Block料盒");
                if (!CheckFlowCondition()) return;
            }
            //检查 横移轴 是否在安全位  方可上下顶升轴
            while (!safetyCheck() && !IsBreak())
            {
                Thread.Sleep(20);
            }
            if (!CheckFlowCondition()) return;

            double offsetHeight = (_lift.MotionPosition["Block料盒终止点"] - _lift.MotionPosition["Block料盒起始点"]) / (10 - 1);

            for (int i = 0; i < 10; i++)
            {
                SingleAxisMove2Point(_lift, _lift.MotionPosition["Block料盒起始点"] + offsetHeight * i + 3);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_transfer, "Block勾取位");
                if (!CheckFlowCondition()) return;
                //走一个偏移
                SingleAxisMove2Point(_lift, _lift.MotionPosition["Block料盒起始点"] + offsetHeight * i);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_transfer, "Block供料位");
                if (!CheckFlowCondition()) return;

                //TODO 检查料盘是否在位
                if(!GlobalVariable.IsDryRun)
                {
                    WaitSensor(_hasPlate, 0, "Block料盘不存在");
                    if (!CheckFlowCondition()) return;
                    //检查 横移轴 是否在安全位  方可上下顶升轴
                    while (!safetyCheck() && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    continue;
                }

                (FlowManager.Instance.SelectFlow("贴合逻辑") as PasteLogic).NewBlockTray();
                SetSignal("Block可取料");
                WaitForSignal("贴合逻辑", "Block取完");
                if (!CheckFlowCondition()) return;
                //把盘子送回去
                SingleAxisMove2Point(_transfer, "Block勾取位");
                if (!CheckFlowCondition()) return;
                //走一个偏移 能让横移轴缩回去
                SingleAxisMove2Point(_lift, _lift.MotionPosition["Block料盒起始点"] + offsetHeight * i + 3);
                if (!CheckFlowCondition()) return;
                SingleAxisMove2Point(_transfer, "等待位");
                if (!CheckFlowCondition()) return;
            }

            SingleAxisMove2Point(_lift, 0);
            if (!CheckFlowCondition()) return;

            ShowWarnAndPause("Block料盒做完,请更换", "Block模组");
            if (!CheckFlowCondition()) return;
        }

        public override void OnStop()
        {
            base.OnStop();
        }

        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }

        public override void SpotCheck()
        {
            base.SpotCheck();
        }
        public void checkProductStatus()
        {
            while (_hasBlockMgz.WaitOn() && !IsBreak())
            {
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"Block料盒存在，请取走", this.Description, 0, "系统"));
                //出错，停下所有线程
                _flowManager.Pause();
                //若为报错，需重新检测启动信号
                WaitForStart();
                if (!CheckFlowCondition()) return;

                Thread.Sleep(20);
            }
        }
        public void checkPlasmaStatus()
        {
            while (_plasmaAlarm.WaitOn() && !IsBreak())
            {
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"等离子机报警中，请检查", this.Description, 0, "系统"));
                //出错，停下所有线程
                _flowManager.Pause();
                //若为报错，需重新检测启动信号
                WaitForStart();
                if (!CheckFlowCondition()) return;

                Thread.Sleep(20);
            }
        }
        private bool safetyCheck()
        {
            return _transfer.Position - _transfer.MotionPosition["等待位"] <= 0.5;
        }
    }
}
